//#include <direct.h>
#include <fstream>
#include <string>
#include "bimg/bimg.h"
#include "bimg/decode.h"
#include "imgui_impl_bfgx.h"
#include "../stringtool/stringconv.h"
#include <unistd.h>
std::u16string __GetShaderResourcePath()
{
	std::u16string shadername = u"resources/shaders/";
	bgfx::RendererType::Enum rtype = bgfx::getRendererType();
	switch (rtype)
	{
	case bgfx::RendererType::Noop:
		break;
	case bgfx::RendererType::Direct3D9:
		shadername += u"dx9/";
		break;
	case bgfx::RendererType::Direct3D11:
		shadername += u"dx11/";
		break;
	case bgfx::RendererType::Direct3D12:
		break;
	case bgfx::RendererType::Gnm:
		break;
	case bgfx::RendererType::Metal:
		shadername += u"metal/";
		break;
	case bgfx::RendererType::Nvn:
		break;
	case bgfx::RendererType::OpenGLES:
		shadername += u"elsl/";
		break;
	case bgfx::RendererType::OpenGL:
		shadername += u"glsl/";
		break;
	case bgfx::RendererType::Vulkan:
		shadername += u"spirv/";
		break;
	case bgfx::RendererType::WebGPU:
		break;
	case bgfx::RendererType::Count:
		break;
	default:
		break;
	}
	return shadername;
}
bgfx::TextureHandle __loadTextureFromMem(const char *mem, uint32_t length, int &texwidth, int &texheight)
{
	auto img = bimg::imageParse(GetAlloc(), mem, length, bimg::TextureFormat::RGBA8, 0);
	texwidth = img->m_width;
	texheight = img->m_height;
	const bgfx::Memory *_mem = bgfx::makeRef(img->m_data, img->m_size);
	bgfx::TextureHandle tex = bgfx::createTexture2D(img->m_width, img->m_height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_NONE, _mem);
	bimg::imageFree(img);
	return tex;
}

bgfx::TextureHandle __LoadTexture(const char16_t *texname, int &texwidth, int &texheight)
{
	auto strName = StringConv::ToUtf8String(texname);

	char buf[256];
	getcwd(buf, 256);
	std::string search1 = "../";
	std::string search2 = "../../";
	std::ifstream file = std::ifstream(strName.c_str(), std::ios_base::binary);
	if (!file)
	{
		std::string sfile = search1 + strName;
		file = std::ifstream(sfile.c_str(), std::ios_base::binary);
	}
	if (!file)
	{
		std::string sfile = search2 + strName;
		file = std::ifstream(sfile.c_str(), std::ios_base::binary);
	}
	if (!file)
	{
		return BGFX_INVALID_HANDLE;
	}
	//step1 ��ʼ��;

	file.seekg(0, std::ios::end);
	int filelen = (int)file.tellg();
	file.seekg(0, std::ios_base::beg);
	char *filecache = new char[filelen];
	file.read(filecache, filelen);
	return __loadTextureFromMem(filecache, filelen, texwidth, texheight);
}

bgfx::ShaderHandle __LoadShader(const char16_t *_shadername)
{
	auto shadername = StringConv::ToUtf8String(__GetShaderResourcePath()) + StringConv::ToUtf8String(_shadername);

	char buf[256];
	getcwd(buf, 256);
	std::string search1 = "../";
	std::string search2 = "../../";
	std::ifstream file = std::ifstream(shadername, std::ios_base::binary);
	if (!file)
	{
		std::string sfile = search1 + shadername;
		file = std::ifstream(sfile.c_str(), std::ios_base::binary);
	}
	if (!file)
	{
		std::string sfile = search2 + shadername;
		file = std::ifstream(sfile.c_str(), std::ios_base::binary);
	}
	if (!file)
	{
		return BGFX_INVALID_HANDLE;
	}
	file.seekg(0, std::ios::end);
	auto filelen = (uint32_t)file.tellg();
	file.seekg(0, std::ios_base::beg);

	auto mem = bgfx::alloc(filelen);
	file.read((char *)mem->data, filelen);
	return bgfx::createShader(mem);
}